<?php

/**
 * @author Anh Nguyen <anhnguyenduy@admicro.vn>
 * @copyright (c) 2013, Anh Nguyen
 */

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class MY_DB_active_record extends CI_DB_active_record
{
    public function insert_batch_duplicate($table = '', $set = NULL, $duplicate = array())
    {
        if (!is_null($set)) {
            $this->set_insert_batch($set);
        }
        
        if (count($this->ar_set) == 0) {
            if ($this->db_debug) {
                //No valid data array.  Folds in cases where keys and values did not match up
                return $this->display_error('db_must_use_set');
            }
            return FALSE;
        }

        if ($table == '') {
            if (!isset($this->ar_from[0])) {
                if ($this->db_debug) {
                    return $this->display_error('db_must_set_table');
                }
                return FALSE;
            }

            $table = $this->ar_from[0];
        }
        
        $duplicateSql = ' ';
        if(is_array($duplicate) && count($duplicate) != 0) {
            $duplicateSql .= 'ON DUPLICATE KEY UPDATE ';
            $duplicateSqlArr = array();
            foreach($duplicate as $colName) {
                $duplicateSqlArr[] = ' ' . $this->_protect_identifiers($colName) . ' = VALUES(' . $this->_protect_identifiers($colName) . ') ';
            }
            $duplicateSql .= implode(',', $duplicateSqlArr);
        }
        
        // Batch this baby
		for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100) {

            $sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));
            $sql = str_replace('INSERT INTO', 'INSERT IGNORE INTO', $sql);
            if ($duplicateSql != '')
                $sql .= $duplicateSql;

            $this->query($sql);
        }
        $this->_reset_write();
        return TRUE;
    }
    
    public function set_insert_batch($key, $value = '', $escape = TRUE)
	{
		$key = $this->_object_to_array_batch($key);

		if ( ! is_array($key))
		{
			$key = array($key => $value);
		}
		$keys = array_keys(current($key));

		foreach ($key as $row)
		{
			if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0)
			{
				// batch function above returns an error on an empty array
				$this->ar_set[] = array();
				return;
			}
            
			if ($escape === FALSE)
			{
				$this->ar_set[] =  '('.implode(',', $row).')';
			}
			else
			{
				$clean = array();

				foreach ($row as $value)
				{
					$clean[] = $this->escape($value);
				}

				$this->ar_set[] =  '('.implode(',', $clean).')';
			}
		}
        
		foreach ($keys as $k)
		{
			$this->ar_keys[] = $this->_protect_identifiers($k);
		}
		return $this;
	}
}